package com.iqiyi.pps.epg.web.webapp.action.auth;

import com.iqiyi.pps.epg.web.utils.Md5PasswordEncoderUtil;
import com.iqiyi.pps.epg.core.dao.base.HibernateUtils;
import com.iqiyi.pps.epg.core.dao.base.Page;
import com.iqiyi.pps.epg.core.dao.base.PropertyFilter;
import com.iqiyi.pps.epg.core.exception.ServiceException;
import com.iqiyi.pps.epg.core.model.auth.Authority;
import com.iqiyi.pps.epg.core.model.auth.Role;
import com.iqiyi.pps.epg.core.model.auth.SysUser;
import com.iqiyi.pps.epg.core.service.auth.AuthorityManager;
import com.iqiyi.pps.epg.core.service.auth.SysUserManager;
import com.iqiyi.pps.epg.core.utils.SpringSecurityUtils;
import com.iqiyi.pps.epg.web.utils.Struts2Utils;
import com.iqiyi.pps.epg.web.webapp.action.BaseAction;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户管理Action.
 * <p/>
 * 使用Struts2 convention-plugin annotation定义Action参数.
 * 演示带分页的管理界面.
 */
//定义URL映射对应/account/user.action
@Namespace("/auth/user")
@Scope("prototype")
//定义名为reload的result重定向到user.action, 其他result则按照convention默认.
@Results({@Result(name = BaseAction.RELOAD, location = "user.action", type = "redirect")})
public class UserAction extends BaseAction<SysUser> {

    private static final long serialVersionUID = 8683878162525847072L;

    private SysUserManager sysUserManager;
    @Autowired
    private AuthorityManager authorityManager;

    //-- 页面属性 --//
    private Long id;
    private SysUser entity;
    private String code;
    private String message;
    private String admin;
    private Page<SysUser> page = new Page<SysUser>(5);//每页5条记录
    private List<Long> checkedRoleIds; //页面中钩选的角色id列表
    private List<Long> checkedAuthIds;
    private List<Authority> allAuthList = new ArrayList<Authority>();

    //-- ModelDriven 与 Preparable函数 --//
    public void setId(Long id) {
        this.id = id;
    }

    public SysUser getModel() {
        return entity;
    }

    public Long getId() {
        return id;
    }

    @Override

    protected void prepareModel() throws Exception {
        if (id != null) {
            entity = sysUserManager.getUser(id);
        } else {
            entity = new SysUser();
        }
    }

    //-- CRUD Action 函数 --//
    @Override
    @Action(value = "list")
    public String list() throws Exception {
        List<PropertyFilter> filters = PropertyFilter.buildFromHttpRequest(Struts2Utils.getRequest());
        //设置默认排序方式
        if (!page.isOrderBySetted()) {
            page.setOrderBy("id");
            page.setOrder(Page.ASC);
        }
        page = sysUserManager.searchUser(page, filters);
        return SUCCESS;
    }

    @Override
    @Action(value = "input")
    public String input() throws Exception {
        checkedRoleIds = entity.getRoleIds();
        checkedAuthIds = entity.getAuthIds();
        if (SpringSecurityUtils.getCurrentUserLoginName().endsWith("admin")) {
            admin = "0";
        } else {
            admin = "1";
        }

        return INPUT;
    }

    @Action(value = "init")
    public String init() throws Exception {

        return SUCCESS;
    }

    @Override
    @Action(value = "save")
    public String save() throws Exception {
        //根据页面上的checkbox选择 整合User的Roles Set

        if (SpringSecurityUtils.getCurrentUserLoginName().endsWith("admin") && admin == null) {
            HibernateUtils.mergeByCheckedIds(entity.getRoleList(), checkedRoleIds, Role.class);
            for (Long id : checkedRoleIds) {
                Role role = sysUserManager.getRole(id);
                if (role != null) {
                    entity.getRoleList().add(role);
                }
            }
            HibernateUtils.mergeByCheckedIds(entity.getAuthList(), checkedAuthIds, Authority.class);
            for (Long id : checkedAuthIds) {
                Authority authority = authorityManager.getAuthority(id);
                if (authority != null) {
                    entity.getAuthList().add(authority);
                }
            }
        }

        checkedRoleIds = entity.getRoleIds();
        checkedAuthIds = entity.getAuthIds();
        if (null == id) {
            entity.setPassword(Md5PasswordEncoderUtil.encode(entity.getPassword()));
            sysUserManager.saveUser(entity);
        } else {
            // 目前暂时处理，后加初始化判断条件
            if (SpringSecurityUtils.getCurrentUserLoginName().endsWith("admin") && admin == null) {
                entity.setPassword(entity.getPassword());
            } else {
                entity.setPassword(Md5PasswordEncoderUtil.encode(entity.getPassword()));
            }
            sysUserManager.saveUser(entity);
        }

        addActionMessage("保存用户成功");
        return INPUT;
    }

    @Override
    @Action(value = "delete")
    public String delete() throws Exception {
        try {
            sysUserManager.deleteUser(id);
            //addActionMessage("删除用户成功");
            message = "操作成功";
            code = "A00000";
        } catch (ServiceException e) {
            logger.error(e.getMessage(), e);
            code = "A00001";
            addActionMessage(e.getMessage());
            message = "操作失败";
            //	addActionMessage("删除用户失败");
        }
        return "verify";
    }

    //-- 其他Action函数 --//

    /**
     * 支持使用Jquery.validate Ajax检验用户名是否重复.
     */
    @Action(value = "check_login_name")
    public String checkLoginName() {
        HttpServletRequest request = ServletActionContext.getRequest();
        String newLoginName = request.getParameter("loginName");
        String oldLoginName = request.getParameter("oldLoginName");

        if (sysUserManager.isLoginNameUnique(newLoginName, oldLoginName)) {
            Struts2Utils.renderText("true");
        } else {
            Struts2Utils.renderText("false");
        }
        //因为直接输出内容而不经过jsp,因此返回null.
        return null;
    }

    //-- 页面属性访问函数 --//

    /**
     * list页面显示用户分页列表.
     */
    public Page<SysUser> getPage() {
        return page;
    }

    /**
     * input页面显示所有角色列表.
     */
    public List<Role> getAllRoleList() {
        return sysUserManager.getAllRole();
    }

    /**
     * input页面显示用户拥有的角色.
     */
    public List<Long> getCheckedRoleIds() {
        return checkedRoleIds;
    }

    /**
     * input页面提交用户拥有的角色.
     */
    public void setCheckedRoleIds(List<Long> checkedRoleIds) {
        this.checkedRoleIds = checkedRoleIds;
    }

    @Autowired
    public void setSysUserManager(SysUserManager sysUserManager) {
        this.sysUserManager = sysUserManager;
    }

    public Map<Boolean, String> getEnabledMap() {
        Map<Boolean, String> enabled = new HashMap<Boolean, String>();
        enabled.put(true, "有效");
        enabled.put(false, "无效");
        return enabled;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getAdmin() {
        return admin;
    }

    public void setAdmin(String admin) {
        this.admin = admin;
    }


    public List<Long> getCheckedAuthIds() {
        return checkedAuthIds;
    }

    public void setCheckedAuthIds(List<Long> checkedAuthIds) {
        this.checkedAuthIds = checkedAuthIds;
    }

    public List<Authority> getAllAuthList() {
        List<Authority> authorities = sysUserManager.getAllAuthority();
        Authority auth = null;
        for(Authority authority: authorities) {
            if(authority.getName().equals("AUTHENTICATED")) {
                auth = authority;
            }
        }

        authorities.remove(auth);
        return authorities;
    }

    public void setAllAuthList(List<Authority> allAuthList) {
        this.allAuthList = allAuthList;
    }

}
